import {
  CMEVENTS,
  pickedFaceData,
  pickedLineData,
  pickedVertexData,
  PickType,
  Types,
} from '@amcax/base';
import { ctx2, docMgr, userEvents } from '@app-cad/module';
import { Vector3 } from 'three-legacy';
import { MARK_EVENT } from '../Constants';
import { useMemoizedFn } from 'ahooks';
import { eventCenterManager } from '../events/EventCenterManager';
import { markManager } from '../managers/MarkManager';

export const useNewMark = (onExit?: VoidFunction) => {
  const onModelSelected = useMemoizedFn(
    (selectedTarget: pickedFaceData | pickedLineData | pickedVertexData) => {
      if (selectedTarget?.assisObj != null) {
        let point: Vector3;

        const documentObject = docMgr.getDocumentObjectById(
          selectedTarget.idInfo.o,
        );

        if (
          [Types.BASIC_PLANE, Types.ORIGIN, Types.Sketcher].includes(
            documentObject?.type,
          )
        ) {
          return;
        }

        if (eventCenterManager.activeEventCenter.mouse != null) {
          const rayCaster = ctx2.viewer.sceneSetup.createRaycaster(
            eventCenterManager.activeEventCenter.mouse.x,
            eventCenterManager.activeEventCenter.mouse.y,
          );

          const res = rayCaster.intersectObject(selectedTarget.assisObj, true);

          point =
            selectedTarget.idInfo.t === PickType.LINE
              ? ((res[0] as any)?.pointOnLine ?? res[0]?.point)
              : res[0]?.point;
        }

        userEvents.emit(MARK_EVENT.NEW_MARK, {
          pickedObj: selectedTarget,
          position:
            (point && new Vector3(point.x, point.y, point.z)) ??
            markManager.getPickedObjCenter(selectedTarget),
        });

        exit();
      }
    },
  );

  const exit = () => {
    userEvents.off(CMEVENTS.MESH_SELECTED, onModelSelected);
    userEvents.off(CMEVENTS.EDGE_SELECTED, onModelSelected);
    userEvents.off(CMEVENTS.POINT_SELECTED, onModelSelected);

    onExit?.();
  };

  const execute = () => {
    userEvents.emit(MARK_EVENT.NEW_MARK, null);

    userEvents.on(CMEVENTS.MESH_SELECTED, onModelSelected);
    userEvents.on(CMEVENTS.EDGE_SELECTED, onModelSelected);
    userEvents.on(CMEVENTS.POINT_SELECTED, onModelSelected);
  };
  return { execute, exit };
};
